//POMModel.h
//Created 17/05/14
//Created By Daniel Bowler
//
//This is an advanced model which is rendered with my Parralax Occlusion Mapping
//effect (POM). This will be shown off in one of the demo scenes. 
//
//Currently it will be a grid, or cube model. POM can be used, however, on 
//arbitary meshes. 
//
//Caveat: Height field must be stored in the .a (.w) component of the normal
//map. A full implementation would handle seperate height maps. 

#pragma once

//This is an advanced model
#include "AbstractAdvancedModel.h"

//Effect used when rendering
class ParallaxOcclusionMappingFX;

class POMModel : public AbstractAdvancedModel
{
public:
	//Standard constructor/destructor - We provide a couple of Init
	//functions which will generate VB and IB for the model.
	POMModel();
	~POMModel();

	//Creates a grid with geo gen.
	void InitAsGrid(ID3D11Device* device, 
		float width, float depth, unsigned vM, unsigned vN, 
		LPCWSTR textureMapFile, LPCWSTR normalHeightFile, 
		LPCWSTR seperateHMFile, bool shouldUseSepHM, 
		LPCWSTR specMapFile, LPCWSTR glossMapFile, 
		bool shouldUseSpecGlossMap);

	//Create a box with geo gen. 
	void InitAsBox(ID3D11Device* device, 
		float width, float height, float depth, 
		LPCWSTR textureMapFile, LPCWSTR normalHeightFile,
		LPCWSTR seperateHMFile, bool shouldUseSepHM, 
		LPCWSTR specMapFile, LPCWSTR glossMapFile, 
		bool shouldUseSpecGlossMap);

public:
	//Set material
	void SetMaterial(Material& m);
	//Set texture transform
	void SetTextureTransform(XMFLOAT2 scale, XMFLOAT2 translation = XMFLOAT2(0.0f, 0.0f));

	//Set POM data
	void SetPOMData(float heightScale, int minSamples, int maxSamples);

private:
	//Override the Render function - Grahics manager calls this (the friendship
	//is inherited)
	void Render(bool isZPrePass, bool isOpaquePass, bool isShadowPass,		   //Flags telling us what pass it is. 
		VirtualCamera* playerCamera,										   //Player camera - passed from GraphicsInterface
		DirecLightShadowMapData* shadowMap,									   //Single shadow map - passed from GraphicsInterface. 
		SSAOData* ssaoMap,													   //SSAO Map.
		ID3D11ShaderResourceView* envMap,									   //Environment map. 
		ID3D11ShaderResourceView* llb,                                         //Light list buffer - gloabl set of lights. 
		ID3D11ShaderResourceView* llibO, ID3D11ShaderResourceView* llsebO,     //Opaque Tile Based Forward buffers. 
		ID3D11ShaderResourceView* llibT, ID3D11ShaderResourceView* llsebT,     //Transparant pass. 
		DirectionalLight* dLightArr, unsigned dLightCount,					   //Directional lights and light count. 
		XMFLOAT3 &hemiColDown, XMFLOAT3 &hemiColRange,						   //Hemispherical ambient lighting data.
		CXMMATRIX &view, CXMMATRIX &proj,									   //Cameras view/proj or the shadow maps view/proj depending on the pass. 
		ID3D11DeviceContext* context);										   //Context we are rendeirng through. 

private:
	//Direct3D resource data
	ID3D11Buffer* vb; //Vertex buffer
	ID3D11Buffer* ib; //Index Buffer
	ID3D11ShaderResourceView* texMap; //Texture map
	ID3D11ShaderResourceView* normalHeightMap; //Normal AND height map (in .a)
	ID3D11ShaderResourceView* sepHeightMap;    //Heightmap is .r componet of this texture. 

	ID3D11ShaderResourceView* specMap; //Specular map (controls intensity)
	ID3D11ShaderResourceView* glossMap; //Controls width of spec cone. 

	//Effect used when rendering this piece of geometry. 
	ParallaxOcclusionMappingFX* effect;

	//Number of indicies
	unsigned indexCount;

	//Reflective properties
	Material material;

	//Texture transformation matrix. 
	XMFLOAT4X4 texTransformation;

private:
	//flag indicating if we are using spec map and gloss map
	bool isUsingSpecGloss;

	//Flag indicating if the POM Model is using a seperate HM. False and we will sample
	//the .a compont of the normal map. 
	bool isUsingSepHM;

	//POM Data
	float heightScalePOM;
	int minSamplesPOM;
	int maxSamplesPOM;
};